gusucode.com > 各种VC自绘控件源码程序 > 各种VC自绘控件源码/code/SkinControls(自绘MFC基本控件 )/SkinControls/SkinControls/SkinListCtrl.cpp
#include "stdafx.h" #include "Resource.h" #include "SkinListCtrl.h" #include "MemDC.h" ////////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC(CSkinListCtrl, CListCtrl) BEGIN_MESSAGE_MAP(CSkinHeaderCtrl, CHeaderCtrl) ON_WM_CREATE() ON_WM_PAINT() ON_WM_ERASEBKGND() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_RBUTTONUP() ON_WM_RBUTTONDOWN() ON_WM_MOUSEMOVE() ON_MESSAGE(HDM_LAYOUT, OnLayout) END_MESSAGE_MAP() BEGIN_MESSAGE_MAP(CSkinListCtrl, CListCtrl) ON_WM_CREATE() ON_WM_ERASEBKGND() ON_WM_MOUSEMOVE() ON_WM_MEASUREITEM_REFLECT() END_MESSAGE_MAP() ////////////////////////////////////////////////////////////////////////// //默认属性 //#define LIST_STYTE LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_ONECLICKACTIVATE|LVS_EX_UNDERLINEHOT|LVS_EX_FLATSB #define LIST_STYTE LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //构造函数 CSkinHeaderCtrl::CSkinHeaderCtrl() { m_iSortCol=-1; m_SortType=Type_NoSort; m_pIHeaderCtrlSink=NULL; m_bEnableDrag = true; m_nHeadHeight = 25; } //析构函数 CSkinHeaderCtrl::~CSkinHeaderCtrl() { } //重画函数 void CSkinHeaderCtrl::OnPaint() { //获取位置 CRect ClientRect; GetClientRect(&ClientRect); //设置自画 HD_ITEM HDItem; HDItem.mask=HDI_FORMAT; int iItemCount=GetItemCount(); for (int i=0;i<iItemCount;i++) { GetItem(i,&HDItem); HDItem.fmt|=HDF_OWNERDRAW; SetItem(i,&HDItem); } //建立缓冲图 CBitmap BufferBmp; CClientDC ClientDC(this); BufferBmp.CreateCompatibleBitmap(&ClientDC,ClientRect.Width(),ClientRect.Height()); m_BufferDC.CreateCompatibleDC(&ClientDC); m_BufferDC.SelectObject(&BufferBmp); m_BufferDC.SetBkMode(TRANSPARENT); //加载位图 if (m_ImageHead.IsValid()) { m_ImageHead.Draw(m_BufferDC.m_hDC, ClientRect); } else { m_BufferDC.FillSolidRect(&ClientRect, RGB(255,255,255)); } if (m_ImageSeparator.IsValid()) { m_ImageSeparator.Draw(m_BufferDC.m_hDC, ClientRect.right-2, (ClientRect.Height()-m_ImageSeparator.GetHeight())/2); } else { CPen pen,pen1; pen.CreatePen(PS_SOLID, 1, RGB(62,178,226)); m_BufferDC.SelectObject(&pen); m_BufferDC.MoveTo(ClientRect.right-1, 6); m_BufferDC.LineTo(ClientRect.right-1, 20); pen1.CreatePen(PS_SOLID, 1, RGB(62,178,226)); m_BufferDC.SelectObject(&pen1); m_BufferDC.MoveTo(ClientRect.left, ClientRect.bottom-1); m_BufferDC.LineTo(ClientRect.right, ClientRect.bottom-1); } Default(); //绘画界面 ClientDC.BitBlt(0,0,ClientRect.Width(),ClientRect.Height(),&m_BufferDC,0,0,SRCCOPY); m_BufferDC.DeleteDC(); BufferBmp.DeleteObject(); return; } LRESULT CSkinHeaderCtrl::OnLayout(WPARAM wParam, LPARAM lParam) { LRESULT lResult = CHeaderCtrl::DefWindowProc(HDM_LAYOUT, wParam, lParam); HDLAYOUT& hdLayout = *reinterpret_cast<LPHDLAYOUT>(lParam); LPRECT lpRect = hdLayout.prc; LPWINDOWPOS lpWindowPos = hdLayout.pwpos; lpRect->top = lpWindowPos->cy = m_nHeadHeight; return lResult; } void CSkinHeaderCtrl::SetHeaderImage(LPCTSTR pszFileName, DWORD imagetype) { m_ImageHead.Load(pszFileName,imagetype); if (m_ImageHead.IsValid()) { m_nHeadHeight = m_ImageHead.GetHeight(); } } void CSkinHeaderCtrl::SetSeparatorImage(LPCTSTR pszFileName, DWORD imagetype) { m_ImageSeparator.Load(pszFileName,imagetype); } //绘画函数 void CSkinHeaderCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { //获取 DC CDC * pDC=NULL; if (m_BufferDC.GetSafeHdc()==NULL) { pDC=CDC::FromHandle(lpDrawItemStruct->hDC); pDC->SetBkMode(TRANSPARENT); } else pDC=&m_BufferDC; CRect rc(lpDrawItemStruct->rcItem); //获取信息 HDITEM HDItem; TCHAR szBuffer[64]; HDItem.pszText=szBuffer; HDItem.mask=HDI_TEXT|HDI_FORMAT; HDItem.cchTextMax=sizeof(szBuffer)/sizeof(szBuffer[0]); CRect rcItemRect=lpDrawItemStruct->rcItem; GetItem(lpDrawItemStruct->itemID,&HDItem); //获取状态 bool bSelected=(lpDrawItemStruct->itemState==ODS_SELECTED); //绘画背景 if (m_ImageHead.IsValid()) { m_ImageHead.Draw(pDC->m_hDC, rcItemRect); } else pDC->FillSolidRect(&rcItemRect, RGB(255,255,255)); if (m_ImageSeparator.IsValid()) { m_ImageSeparator.Draw(pDC->m_hDC, rcItemRect.right-2, (rcItemRect.Height()-m_ImageSeparator.GetHeight())/2); } else { CPen pen,pen1; pen.CreatePen(PS_SOLID, 1, RGB(62,178,226)); pDC->SelectObject(&pen); pDC->MoveTo(rcItemRect.right-1, 6); pDC->LineTo(rcItemRect.right-1, 20); pen1.CreatePen(PS_SOLID, 1, RGB(62,178,226)); pDC->SelectObject(&pen1); pDC->MoveTo(rcItemRect.left, rcItemRect.bottom-1); pDC->LineTo(rcItemRect.right, rcItemRect.bottom-1); } rcItemRect.DeflateRect(5,0,5,0); //绘画标志 if ((m_iSortCol==lpDrawItemStruct->itemID)&&(m_SortType!=Type_NoSort)) { if (rcItemRect.Width()>=14) { int nXOff=0,nYPos=(rcItemRect.Height()-9)/2+rcItemRect.top; if (bSelected) { nYPos++; nXOff++; } CPen * pWhitePen=CPen::FromHandle((HPEN)GetStockObject(WHITE_PEN)); CPen * pBlackPen=CPen::FromHandle((HPEN)GetStockObject(BLACK_PEN)); if (m_SortType==Type_Ascend) { pDC->SelectObject(pWhitePen); pDC->MoveTo(rcItemRect.right-5+nXOff,nYPos); pDC->LineTo(rcItemRect.right-14+nXOff,nYPos); pDC->LineTo(rcItemRect.right-10+nXOff,nYPos+9); pDC->SelectObject(pBlackPen); pDC->LineTo(rcItemRect.right-5+nXOff,nYPos); } else { pDC->SelectObject(pWhitePen); pDC->MoveTo(rcItemRect.right-10+nXOff,nYPos); pDC->LineTo(rcItemRect.right-14+nXOff,nYPos+9); pDC->LineTo(rcItemRect.right-5+nXOff,nYPos+9); pDC->SelectObject(pBlackPen); pDC->LineTo(rcItemRect.right-10+nXOff,nYPos); } } rcItemRect.right-=19; } //绘画标题字体 UINT uFormat=DT_WORDBREAK|DT_EDITCONTROL|DT_END_ELLIPSIS|DT_SINGLELINE|DT_VCENTER; CFont font; font.CreateFont(-12,0,0,0,400,0,0,0,134,3,2,1,2,TEXT("宋体")); pDC->SelectObject(&font); if (bSelected) rcItemRect.OffsetRect(1,1); pDC->DrawText(HDItem.pszText,lstrlen(HDItem.pszText),&rcItemRect,uFormat|DT_CENTER); return; } //背景函数 BOOL CSkinHeaderCtrl::OnEraseBkgnd(CDC * pDC) { return TRUE; } //获取标题 LPCTSTR CSkinHeaderCtrl::GetItemText(int iCol, TCHAR szBuffer[], int nSize) { ASSERT(szBuffer!=NULL); if (iCol<GetItemCount()) { HDITEM HDItem; HDItem.pszText=szBuffer; HDItem.mask=HDI_TEXT; HDItem.cchTextMax=nSize; GetItem(iCol,&HDItem); } else szBuffer[0]=0; return szBuffer; } //坐标转换 int CSkinHeaderCtrl::PointToColIndex(CPoint Point) { CRect rcItemRect; int iItemCount=GetItemCount(); for (int i=0;i<iItemCount;i++) { GetItemRect(i,&rcItemRect); if (rcItemRect.PtInRect(Point)) return i; } return -1; } //设置标志 void CSkinHeaderCtrl::SetSortArrow(int iSortCol, enHeaderSortType SortType) { m_iSortCol=iSortCol; m_SortType=SortType; Invalidate(FALSE); return; } //获取标志 void CSkinHeaderCtrl::GetSortArrow(int & iSortCol, enHeaderSortType & SortType) { iSortCol=m_iSortCol; SortType=m_SortType; return; } //鼠标消息 void CSkinHeaderCtrl::OnLButtonDown(UINT nFlags, CPoint point) { if (m_pIHeaderCtrlSink!=NULL) m_pIHeaderCtrlSink->OnHeaderLButtonDown(this,nFlags,point); if (m_bEnableDrag) CHeaderCtrl::OnLButtonDown(nFlags, point); else return; } //鼠标消息 void CSkinHeaderCtrl::OnLButtonUp(UINT nFlags, CPoint point) { if (m_pIHeaderCtrlSink!=NULL) m_pIHeaderCtrlSink->OnHeaderLButtonUp(this,nFlags,point); if (m_bEnableDrag) CHeaderCtrl::OnLButtonUp(nFlags, point); else return; } //鼠标消息 void CSkinHeaderCtrl::OnRButtonUp(UINT nFlags, CPoint point) { if (m_pIHeaderCtrlSink!=NULL) m_pIHeaderCtrlSink->OnHeaderRButtonUp(this,nFlags,point); CHeaderCtrl::OnRButtonUp(nFlags, point); } //鼠标消息 void CSkinHeaderCtrl::OnRButtonDown(UINT nFlags, CPoint point) { if (m_pIHeaderCtrlSink!=NULL) m_pIHeaderCtrlSink->OnHeaderRButtonDown(this,nFlags,point); CHeaderCtrl::OnRButtonDown(nFlags, point); } void CSkinHeaderCtrl::OnMouseMove(UINT nFlags, CPoint point) { if (m_bEnableDrag) CHeaderCtrl::OnMouseMove(nFlags, point); else return; } ////////////////////////////////////////////////////////////////////////// //构造函数 CSkinListCtrl::CSkinListCtrl() { m_nMoveItem = -1; } //析构函数 CSkinListCtrl::~CSkinListCtrl() { } //控件绑定 void CSkinListCtrl::PreSubclassWindow() { __super::PreSubclassWindow(); m_SkinHeadCtrl.SubclassWindow(GetHeaderCtrl()->GetSafeHwnd()); SetExtendedStyle(LIST_STYTE); return; } //建立消息 int CSkinListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (__super::OnCreate(lpCreateStruct)==-1) return -1; m_SkinHeadCtrl.SubclassWindow(GetHeaderCtrl()->GetSafeHwnd()); SetExtendedStyle(LIST_STYTE); return 0; } void CSkinListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { CRect rcItem=lpDrawItemStruct->rcItem; CDC * pDC=CDC::FromHandle(lpDrawItemStruct->hDC); int iItem=lpDrawItemStruct->itemID; int iCount=GetHeaderCtrl()->GetItemCount(); int iBeen=rcItem.left; TCHAR szBuffer[1024]; CFont font; font.CreateFont(-12,0,0,0,400,0,0,0,134,3,2,1,2,TEXT("宋体")); pDC->SelectObject(&font); GetItemRect(iItem, rcItem, LVIR_LABEL); for (int i=0;i<iCount;i++) { CRect rcSubItem; int iWidth=GetColumnWidth(i); GetSubItemRect(iItem,i,LVIR_LABEL,rcSubItem); if (lpDrawItemStruct->itemState&ODS_FOCUS) pDC->FillSolidRect(&rcSubItem,RGB(40,82,144)); else if (m_nMoveItem == iItem) pDC->FillSolidRect(&rcSubItem,RGB(194,255,246)); else pDC->FillSolidRect(&rcSubItem,GetBkColor()); GetItemText(iItem,i,szBuffer,sizeof(szBuffer)); rcSubItem.left+=3; pDC->DrawText(szBuffer,lstrlen(szBuffer),rcSubItem,DT_LEFT|DT_VCENTER|DT_END_ELLIPSIS|DT_SINGLELINE); } return; } void CSkinListCtrl::OnMouseMove(UINT nFlags, CPoint point) { LVHITTESTINFO lht; lht.pt = point; lht.flags = LVHT_ABOVE; int nItem = SubItemHitTest(&lht); if(m_nMoveItem != nItem) { CRect rc; if (m_nMoveItem != -1) GetItemRect(m_nMoveItem, &rc,LVIR_BOUNDS); m_nMoveItem = lht.iItem; InvalidateRect(&rc, FALSE); if (m_nMoveItem != -1) GetItemRect(m_nMoveItem, &rc,LVIR_BOUNDS); InvalidateRect(&rc, FALSE); } return __super::OnMouseMove(nFlags, point); } //绘画背景 BOOL CSkinListCtrl::OnEraseBkgnd(CDC * pDC) { if (m_SkinHeadCtrl.GetSafeHwnd()) { CRect ClientRect,ListHeaderRect; GetClientRect(&ClientRect); m_SkinHeadCtrl.GetWindowRect(&ListHeaderRect); ClientRect.top=ListHeaderRect.Height(); pDC->FillSolidRect(&ClientRect,GetBkColor()); return TRUE; } return __super::OnEraseBkgnd(pDC); } void CSkinListCtrl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { lpMeasureItemStruct-> itemHeight = 20; //这个就是你要设置的高度 } //////////////////////////////////////////////////////////////////////////